﻿/*
* This software is licensed under the GNU General Public License, version 2
* You may copy, distribute and modify the software as long as you track changes/dates of in source files and keep all modifications under GPL. You can distribute your application using a GPL library commercially, but you must also provide the source code.

* DNNspot Software (http://www.dnnspot.com)
* Copyright (C) 2013 Atriage Software LLC
* Authors: Kevin Southworth, Matthew Hall, Ryan Doom

* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.

* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.

* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

* Full license viewable here: http://www.gnu.org/licenses/gpl-2.0.txt
*/

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Modules.Actions;
using DotNetNuke.Entities.Users;
using System.Collections;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Security;

namespace DNNspot.BecomeUser
{
    public partial class Default : PortalModuleBase
    {
        bool debugmode = false;
        bool showSearch = true;
        bool autoLoad = true;
        bool hideAdmin = false;
        int maxUsers = int.MaxValue;
        List<UserInfo> userList = new List<UserInfo>();


        protected void Page_Load(object sender, EventArgs e)
        {
            debugmode = false;
            ltDebugData.Visible = debugmode;
            
            
            if (Settings["showSearch"] != null)
            {
                showSearch = Convert.ToBoolean(Settings["showSearch"]);
            }
            if (Settings["hideAdmin"] != null)
            {
                hideAdmin = Convert.ToBoolean(Settings["hideAdmin"]);
            }
            if(Settings["autoLoad"] != null)
            {
                autoLoad = Convert.ToBoolean(Settings["autoLoad"]);
            }

            if (!autoLoad)
                dropsearch.Visible = false;

            ltDebugData.Text += "autoload=" + autoLoad.ToString() + "<br/>";
            ltDebugData.Text += "showsearch=" + showSearch.ToString() + "<br/>";
            ltDebugData.Text += hideAdmin.ToString() + "<br />";

                pnlSearchUser.Visible = showSearch;
            
            //FillListControls();
            if (!IsPostBack)  //IF NOT - Clicked Search or become user or other module posted back
            {
                LoadUsers();
                ltDebugData.Text+="!IsPostBack<br/>";
                if (autoLoad)  //If NoLoad option is true then don't load the users by default
                {
                    FillListControls();
                    ltDebugData.Text += "autoload=" + autoLoad.ToString() + " FillListControls()<br/>";
                }
            }


            if (UserId > 0)
            {
                mainContent.Text = "<p><strong>Current User</strong><br/>Display Name: " + UserInfo.DisplayName + "<br/>";
                mainContent.Text += "Email: " + UserInfo.Email + "<br/></p>";
                string[] roles = UserInfo.Roles;

                for (int i = 0; i < roles.Length; i++)
                    mainContent.Text += roles[i].ToString() + "<br/>";

                ltDebugData.Text += "userid" + UserId.ToString() + " > 0 <br/>";
            }
            else
            {
                mainContent.Visible = false;
            }

            ltDebugData.Text += "loaded users is " + userList.Count.ToString()+"<br/>";
        }

        protected void btnBecomeUser_Click(object sender, EventArgs e)
        {
            ltDebugData.Text += "Become User click " + drpUserList.SelectedValue.ToString();
            if (!string.IsNullOrEmpty(drpUserList.SelectedValue))
            {
                BecomeUser(Int32.Parse(drpUserList.SelectedValue));
            }
            else
            {
                ltDebugData.Text += "Nothing selected in dropdown <br/>";
            }            
        }

        private void LoadUsers()
        {            
            userList = new List<UserInfo>();
            ArrayList allUsers = UserController.GetUsers(PortalId, true);
            if(hideAdmin)
            {
                foreach (object t in allUsers)
                {
                    UserInfo user = (UserInfo) t;

                    if (!user.IsInRole("Administrators"))
                    {
                        userList.Add(user);
                    }

                    ltDebugData.Text += user.Username + " " + !user.IsInRole("Administrators") + "<br />";
                }
            }
            else
            {
                foreach (object t in allUsers)
                {
                    userList.Add((UserInfo) t);
                }
            }

            userList.Sort((left, right) => left.Username.CompareTo(right.Username));

            ltDebugData.Text += "LoadUsers()<br/>";
        }

        private void FillListControls()
        {
            int foundusers = 0;
            drpUserList.Items.Clear();
            foreach (UserInfo user in userList)
            {
                drpUserList.Items.Add(new ListItem(user.Username + " | " + user.Email + " | " + user.DisplayName, user.UserID.ToString()));

                if (foundusers >= maxUsers)
                    break;

                foundusers++;
            }
            ltDebugData.Text += "FillListControls() foundusers="+ foundusers.ToString()+" maxUsers="+maxUsers.ToString()+"<br/>";
        }

        private void FilterUsers(string SearchTerm)
        {
            SearchTerm = SearchTerm.ToLower();

            drpUserList.Items.Clear();

            int foundusers = 0;

            if (userList.Count == 0)
                LoadUsers();


            foreach (UserInfo user in userList)
            {
                if (SearchTerm.Length == 0 || user.Username.ToLower().Contains(SearchTerm) || user.DisplayName.ToLower().Contains(SearchTerm) || user.FirstName.ToLower().Contains(SearchTerm) || user.LastName.ToLower().Contains(SearchTerm) || user.Email.ToLower().Contains(SearchTerm))
                {                    
                    drpUserList.Items.Add(new ListItem(user.Username + " | " + user.Email + " | " + user.DisplayName, user.UserID.ToString()));

                    if(foundusers > maxUsers)
                        break;
                    
                    foundusers++;
                }                
            }

            ltDebugData.Text += "FilterUsers(" + SearchTerm + ")<br/>";

            ltHowManyUsers.Text = "<strong>"+foundusers.ToString() + " Users";
            if (foundusers != userList.Count)
                ltHowManyUsers.Text += " of " + userList.Count.ToString();
            ltHowManyUsers.Text += "</strong>";

            dropsearch.Visible = true;
        }

        private void BecomeUser(int userId)
        {
            DataCache.ClearUserCache(PortalSettings.PortalId,Context.User.Identity.Name);
            PortalSecurity portalSecurity = new PortalSecurity();
            portalSecurity.SignOut();                             

            UserInfo userInfo;
            PortalSettings portalSettings = PortalController.GetCurrentPortalSettings();

            userInfo = UserController.GetUser(PortalId, userId, true);            

            if (userInfo != null)
            {
                UserController.UserLogin(PortalId, userInfo, portalSettings.PortalName, HttpContext.Current.Request.UserHostAddress, false);
                Response.Redirect(Request.UrlReferrer.AbsoluteUri);
            }
            ltDebugData.Text += "BecomeUser(" + userId.ToString() + ")<br/>)";
        }

        private void SearchUsers(string SearchTerm)
        {
            dropsearch.Visible = true;
            FilterUsers(txtSearchText.Text);
            ltDebugData.Text += "SearchUsers("+SearchTerm+")<br/>";
        }


        protected void btnSearchButton_Click(object sender, EventArgs e)
        {
            //load search drop down.

            if(!autoLoad)
            {
                LoadUsers();
            }

            SearchUsers(txtSearchText.Text);
        }

        protected void lnkClearSearch_Click(object sender, EventArgs e)
        {
            txtSearchText.Text = "";
            if(!autoLoad)
            {
                LoadUsers();
            }
            SearchUsers("");
        }
    }
}